package org.word.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.word.model.Response;
import org.word.model.definition.SwaggerModelDefinition;
import org.word.model.definition.SwaggerModelDefinitionRef;
import org.word.model.definition.SwaggerModelProperty;
import org.word.model.path.ParameterItem;
import org.word.model.path.PathVOForPost;
import org.word.model.path.ResponeVOForSuccess;
import org.word.model.path.ResponseVO;
import org.word.utils.ModelDefinitionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static org.word.utils.ModelDefinitionUtils.fillChildPropertiesOfCurrentProperty;
import static org.word.utils.ModelDefinitionUtils.getChildPropertiesOfProperty;

@Service
@Slf4j
public class ResponseParamServiceImpl implements ResponseParamService {
    @Autowired
    private ModelDefinitionService modelDefinitionService;

    @Override
    public List<Response> getResponseParameterList(PathVOForPost pathVOForPost) {
        LinkedHashMap<String, SwaggerModelDefinition> definitionMap = modelDefinitionService.getDefinitionMap();
        ResponseVO responses = pathVOForPost.getResponses();
        ResponeVOForSuccess ret200 = responses.getRet200();

        SwaggerModelDefinitionRef schema = ret200.getSchema();
        if (schema == null) {
            return new ArrayList<>();
        }

        String definitionNameFromRef = ModelDefinitionUtils.getDefinitionNameFromRef(schema.getRef());
        SwaggerModelDefinition swaggerModelDefinition = definitionMap.get(definitionNameFromRef);
        if (swaggerModelDefinition == null) {
            throw new RuntimeException();
        }

        String type = swaggerModelDefinition.getType();
        if (!"object".equals(type)) {
            throw new RuntimeException();
        }

        LinkedHashMap<String, SwaggerModelProperty> map = swaggerModelDefinition.getProperties();
        Collection<SwaggerModelProperty> values = map.values();
        /**
         * 遍历对象的property
         */
        ArrayList<ParameterItem> parameterItems = new ArrayList<>();
        for (SwaggerModelProperty swaggerModelProperty : values) {

            /**
             * 先把当前属性加入到结果
             */
            {
                ParameterItem childParameterItem = new ParameterItem();
                childParameterItem.setLevel(swaggerModelProperty.getLevel());
                childParameterItem.setName(swaggerModelProperty.getKey());
                childParameterItem.setIn(null);
                childParameterItem.setType(swaggerModelProperty.getType());
                childParameterItem.setDescription(swaggerModelProperty.getDescription());
                childParameterItem.setRequired(true);
                childParameterItem.setSchema(null);

                parameterItems.add(childParameterItem);
            }

            /**
             * 假设此时的properties如下，
             * 那么，在访问disposalUserSet的时候，又要访问内部的bean
             *
             * "properties": {
             *         "onOffStatus": {
             *           "type": "integer",
             *           "format": "int32",
             *           "description": "开关状态，0：关闭；1：打开"
             *         },
             *         "disposalUserSet": {
             *           "type": "array",
             *           "description": "处警人员的集合",
             *           "items": {
             *             "$ref": "#/definitions/CadCommonUserVO"
             *           }
             *         }
             *       },
             *
             */
            HashSet<String> visitedDefinitionSet = new HashSet<>();

            List<SwaggerModelProperty> childModelPropertiesList = getChildPropertiesOfProperty(visitedDefinitionSet,swaggerModelProperty,definitionMap);
            if (CollectionUtils.isEmpty(childModelPropertiesList)) {
                continue;
            }

            /**
             * 修改
             */
            fillChildPropertiesOfCurrentProperty(null, parameterItems, childModelPropertiesList);
        }

        if (CollectionUtils.isEmpty(parameterItems)) {
            return new ArrayList<>();
        }

        List<Response> responseList = parameterItems.stream().map(item -> {
            Response response = new Response();
            StringBuilder builder = new StringBuilder();
            for (int i = 1; i < item.getLevel(); i++) {
                builder.append("-- ");
            }
            response.setName(builder.toString() + item.getName());
            response.setParamType(item.getType());
            response.setType(item.getIn());
            response.setRequire(item.getRequired());
            response.setRemark(item.getDescription());

            return response;

        }).collect(Collectors.toList());

        return responseList;
    }
}
